package com.zenithmind.coding.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zenithmind.coding.pojo.entity.Problem;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 编程问题Mapper接口
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Mapper
public interface ProblemMapper extends BaseMapper<Problem> {

    /**
     * 分页查询问题列表
     * 
     * @param page 分页参数
     * @param categoryId 分类ID
     * @param difficulty 难度等级
     * @param type 问题类型
     * @param status 问题状态
     * @param keyword 关键词
     * @param tags 标签列表
     * @return 问题列表
     */
    IPage<Problem> selectProblemPage(Page<Problem> page,
                                    @Param("categoryId") String categoryId,
                                    @Param("difficulty") Integer difficulty,
                                    @Param("type") Integer type,
                                    @Param("status") Integer status,
                                    @Param("keyword") String keyword,
                                    @Param("tags") List<String> tags);

    /**
     * 查询推荐问题
     * 
     * @param userId 用户ID
     * @param difficulty 难度等级
     * @param limit 限制数量
     * @return 问题列表
     */
    List<Problem> selectRecommendProblems(@Param("userId") String userId,
                                         @Param("difficulty") Integer difficulty,
                                         @Param("limit") Integer limit);

    /**
     * 查询热门问题
     * 
     * @param limit 限制数量
     * @return 问题列表
     */
    List<Problem> selectHotProblems(@Param("limit") Integer limit);

    /**
     * 查询相关问题
     * 
     * @param problemId 问题ID
     * @param limit 限制数量
     * @return 问题列表
     */
    List<Problem> selectRelatedProblems(@Param("problemId") String problemId,
                                       @Param("limit") Integer limit);

    /**
     * 根据标签查询问题
     * 
     * @param tags 标签列表
     * @param limit 限制数量
     * @return 问题列表
     */
    List<Problem> selectProblemsByTags(@Param("tags") List<String> tags,
                                      @Param("limit") Integer limit);

    /**
     * 搜索问题
     * 
     * @param keyword 关键词
     * @param limit 限制数量
     * @return 问题列表
     */
    List<Problem> searchProblems(@Param("keyword") String keyword,
                                @Param("limit") Integer limit);

    /**
     * 更新问题统计信息
     * 
     * @param problemId 问题ID
     * @param submitCount 提交次数增量
     * @param acceptCount 通过次数增量
     * @return 更新行数
     */
    int updateStatistics(@Param("problemId") String problemId,
                        @Param("submitCount") Long submitCount,
                        @Param("acceptCount") Long acceptCount);

    /**
     * 更新问题平均性能
     * 
     * @param problemId 问题ID
     * @param avgTime 平均用时
     * @param avgMemory 平均内存
     * @return 更新行数
     */
    int updateAvgPerformance(@Param("problemId") String problemId,
                            @Param("avgTime") Integer avgTime,
                            @Param("avgMemory") Integer avgMemory);

    /**
     * 查询问题统计信息
     * 
     * @param categoryId 分类ID
     * @param difficulty 难度等级
     * @return 统计信息
     */
    ProblemStatistics selectProblemStatistics(@Param("categoryId") String categoryId,
                                             @Param("difficulty") Integer difficulty);

    /**
     * 查询热门标签
     * 
     * @param limit 限制数量
     * @return 标签列表
     */
    List<TagStatistics> selectHotTags(@Param("limit") Integer limit);

    /**
     * 查询用户解题统计
     * 
     * @param userId 用户ID
     * @return 解题统计
     */
    UserSolveStatistics selectUserSolveStatistics(@Param("userId") String userId);

    /**
     * 查询每日挑战问题
     * 
     * @param userId 用户ID
     * @param date 日期
     * @param count 数量
     * @return 问题列表
     */
    List<Problem> selectDailyChallenges(@Param("userId") String userId,
                                       @Param("date") String date,
                                       @Param("count") Integer count);

    /**
     * 问题统计信息
     */
    class ProblemStatistics {
        private Long totalProblems;
        private Long easyProblems;
        private Long mediumProblems;
        private Long hardProblems;
        private Long expertProblems;
        private Double avgAcceptRate;
        private String mostPopularTag;
        private String mostDifficultProblem;

        // Getters and Setters
        public Long getTotalProblems() { return totalProblems; }
        public void setTotalProblems(Long totalProblems) { this.totalProblems = totalProblems; }
        
        public Long getEasyProblems() { return easyProblems; }
        public void setEasyProblems(Long easyProblems) { this.easyProblems = easyProblems; }
        
        public Long getMediumProblems() { return mediumProblems; }
        public void setMediumProblems(Long mediumProblems) { this.mediumProblems = mediumProblems; }
        
        public Long getHardProblems() { return hardProblems; }
        public void setHardProblems(Long hardProblems) { this.hardProblems = hardProblems; }
        
        public Long getExpertProblems() { return expertProblems; }
        public void setExpertProblems(Long expertProblems) { this.expertProblems = expertProblems; }
        
        public Double getAvgAcceptRate() { return avgAcceptRate; }
        public void setAvgAcceptRate(Double avgAcceptRate) { this.avgAcceptRate = avgAcceptRate; }
        
        public String getMostPopularTag() { return mostPopularTag; }
        public void setMostPopularTag(String mostPopularTag) { this.mostPopularTag = mostPopularTag; }
        
        public String getMostDifficultProblem() { return mostDifficultProblem; }
        public void setMostDifficultProblem(String mostDifficultProblem) { this.mostDifficultProblem = mostDifficultProblem; }
    }

    /**
     * 标签统计信息
     */
    class TagStatistics {
        private String tag;
        private Long count;
        private Double avgDifficulty;
        private Double avgAcceptRate;

        // Getters and Setters
        public String getTag() { return tag; }
        public void setTag(String tag) { this.tag = tag; }
        
        public Long getCount() { return count; }
        public void setCount(Long count) { this.count = count; }
        
        public Double getAvgDifficulty() { return avgDifficulty; }
        public void setAvgDifficulty(Double avgDifficulty) { this.avgDifficulty = avgDifficulty; }
        
        public Double getAvgAcceptRate() { return avgAcceptRate; }
        public void setAvgAcceptRate(Double avgAcceptRate) { this.avgAcceptRate = avgAcceptRate; }
    }

    /**
     * 用户解题统计
     */
    class UserSolveStatistics {
        private String userId;
        private Long totalSolved;
        private Long easySolved;
        private Long mediumSolved;
        private Long hardSolved;
        private Long expertSolved;
        private Long totalSubmissions;
        private Double acceptRate;
        private Integer ranking;
        private Integer totalPoints;

        // Getters and Setters
        public String getUserId() { return userId; }
        public void setUserId(String userId) { this.userId = userId; }
        
        public Long getTotalSolved() { return totalSolved; }
        public void setTotalSolved(Long totalSolved) { this.totalSolved = totalSolved; }
        
        public Long getEasySolved() { return easySolved; }
        public void setEasySolved(Long easySolved) { this.easySolved = easySolved; }
        
        public Long getMediumSolved() { return mediumSolved; }
        public void setMediumSolved(Long mediumSolved) { this.mediumSolved = mediumSolved; }
        
        public Long getHardSolved() { return hardSolved; }
        public void setHardSolved(Long hardSolved) { this.hardSolved = hardSolved; }
        
        public Long getExpertSolved() { return expertSolved; }
        public void setExpertSolved(Long expertSolved) { this.expertSolved = expertSolved; }
        
        public Long getTotalSubmissions() { return totalSubmissions; }
        public void setTotalSubmissions(Long totalSubmissions) { this.totalSubmissions = totalSubmissions; }
        
        public Double getAcceptRate() { return acceptRate; }
        public void setAcceptRate(Double acceptRate) { this.acceptRate = acceptRate; }
        
        public Integer getRanking() { return ranking; }
        public void setRanking(Integer ranking) { this.ranking = ranking; }
        
        public Integer getTotalPoints() { return totalPoints; }
        public void setTotalPoints(Integer totalPoints) { this.totalPoints = totalPoints; }
    }
}
